package com.mike.mybatisplus.service;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @ Author     ：mmzs.
 * @ Date       ：Created in  2021/11/30 19:43
 * @ Description：实现 AOP
 */
// 开启 AOP 支持
@Aspect
@Component
public class AOP {

    @Pointcut("execution(* com.mike.mybatisplus.service.StudentServiceImpl.*(..))")
    public void operateMethod () {
        System.err.println("正在扫描包...");
    }

    // 方法执行前  execution(全局扫描 需AOP支持路径.需AOP支持对象.所有方法(所有参数))
    @Before("operateMethod()")
    public void before() {
        System.out.println("正在操作数据库...");
    }

    @Around("operateMethod()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("正在启动环绕通知...");
        System.out.println("获取 数据库 类： " + pjp.getThis());
        System.out.println("获取 数据库 方法名： " + pjp.getSignature().getName());
        System.out.println("获取 数据库 方法相关信息： " + pjp.getSignature());
        System.out.println("获取 数据库 参数： " + pjp.getArgs());
        System.out.println("获取 数据库 返回值： " + pjp.proceed());
        Object[] args = pjp.getArgs();
        String[] names = ((CodeSignature) pjp.getSignature()).getParameterNames();
        for (int i = 0; i < names.length; i++) {
            System.out.println("参数 " + names[i] + "\t值 " + args[i]);
        }
        System.out.println("获取 代理对象 " + pjp.getThis());
        System.out.println("获取 被代理对象 " + pjp.getTarget());
        System.out.println("环绕通知已结束！！！");
    }

    @After("operateMethod()")
    public void after() {
        System.out.println("操作数据库完毕！！！");
    }

    // 正常返回通知
    @AfterReturning("operateMethod()")
    public void afterReturning () {
        System.out.println("数据库操作一切正常...");
    }

    // 数据库异常返回通知
    @AfterThrowing(value = "operateMethod()", throwing = "e")
    public void afterThrowing (JoinPoint joinPoint, Throwable e) {
        System.out.println(" -----------------------------------------------");
        System.out.println("被代理对象 "+ joinPoint.getTarget());
        System.out.println("代理对象"+ joinPoint.getThis());
        Object[] args = joinPoint.getArgs();
        String[] names = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < names.length; i++) {
            System.out.println("参数 " + names[i] + "\t值 " + args[i]);
        }
        System.err.println("数据库程出现异常...");
        System.out.println(e);
    }
}